home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
- /* [yeah, right, the Interface Builder generated this. -scott] */
-
- // My stuff.
- #import "ClockView.h"
- #import "Animator.h"
-
- // appkit stuff.
- #import <appkit/nextstd.h> // MAX()
- #import <appkit/Matrix.h> // For getting the clockType.
-
- // unix stuff.
- #import <math.h> // cos, sin, M_PI
-
- // dps stuff.
- #import <dpsclient/wraps.h> // PS*().
-
- @implementation ClockView
-
- extern long time( long *);
-
- + newFrame:(NXRect *)r
- {
- self = [super newFrame:r];
- [self setClockType:BEZIER];
- [self setDialSize:.05];
- return self;
- }
-
- - free
- {
- [animator stop:self];
- [animator setTarget:nil];
- return [super free];
- }
-
- - takeDialSizeFrom:sender // set the dial size via slider.
- {
- return [self setDialSize:[sender floatValue]];
- }
- - takeClockTypeFrom:sender // set the clock type via matrix.
- {
- return [self setClockType:[[sender selectedCell] tag]];
- }
-
- - setDialSize:(float)size // Set programatically.
- {
- dialSize=size;
- return [self display];
- }
- - setClockType:(int)type
- {
- clockType=type;
- return [self display];
- }
-
- -(int)clockType // return the data.
- {
- return clockType;
- }
- -(float)dialSize
- {
- return dialSize;
- }
-
- // Draws the dials in the currently focussed region, etc. Makes little or
- // no sense if not used to draw in this view. Also, won't work nicely for non-
- // square views.
- - drawDials
- {
- float half=bounds.size.height/2.0;
- float secang=sec*6*M_PI/180.0;
- float minang=min*6*M_PI/180.0;
- float hourang=((hour)%12)*30*M_PI/180.0+minang/12;
-
- // define the size multiplier for each hand.
- #define HOUR (.4*half)
- #define MINUTE (.75*half)
- #define SECOND (.85*half)
-
- PSsetlinewidth( dialSize*half);
- PSsetlinecap( 1); // Rounded ends.
- PSsetlinejoin( 1); // Rounded joins.
- PStranslate( half, half);
- PSmoveto( sin( minang)*MINUTE, cos( minang)*MINUTE);
- switch( clockType)
- {
- case NORMAL : // "Normal" clock.
- PSlineto( 0, 0);
- PSlineto( sin( secang)*SECOND, cos( secang)*SECOND);
- PSlineto( 0, 0);
- PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR);
- break;
- case LINES :
- PSlineto( sin( secang)*SECOND, cos( secang)*SECOND);
- PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR);
- break;
- case CURVES :
- PScurveto( 0, 0, 0, 0,
- sin( secang)*SECOND, cos( secang)*SECOND);
- PScurveto( 0, 0, 0, 0,
- sin( hourang)*HOUR, cos( hourang)*HOUR);
- PScurveto( 0, 0, 0, 0,
- sin( minang)*MINUTE, cos( minang)*MINUTE);
- break;
- case BEZIER :
- PScurveto( sin( secang)*SECOND, cos( secang)*SECOND,
- 0, 0, sin( hourang)*HOUR, cos( hourang)*HOUR);
- break;
- }
- PSstroke();
- PStranslate( -half, -half);
- return self;
- }
-
- - setAnimator:anObject
- {
- if( animator==anObject) // nip loops in the bud.
- return self;
- animator=anObject;
- [animator setTarget:self];
- [animator setTiming:1.0];
- [animator setThreshold:NX_MODALRESPTHRESHOLD]; // this makes it run smoother. why?
- return self;
- }
-
- - animate:sender
- {
- long clock;
- struct tm *t;
-
- [self lockFocus];
-
- PSsetgray( NX_LTGRAY); // Erase the old time.
- [self drawDials];
-
- time( &clock); // Snarf the new time.
- t=localtime( &clock);
- hour=t->tm_hour;
- min=t->tm_min;
- sec=t->tm_sec;
-
- PSsetgray( NX_BLACK); // Draw the new time.
- [self drawDials];
-
- [self unlockFocus]; // Make it be.
- [[self window] flushWindow];
- NXPing();
- return self;
- }
-
- - animator
- {
- return animator;
- }
-
- - drawSelf:(NXRect *)r :(int)count
- {
- long clock;
- struct tm *t;
- int i;
- float half=bounds.size.height/2.0;
- #define TICKS (.95*half)
-
- time( &clock); // Snarf the time.
- t=localtime( &clock);
- hour=t->tm_hour;
- min=t->tm_min;
- sec=t->tm_sec;
-
- PSsetgray( NX_LTGRAY); // Clear the background.
- NXRectFill( &bounds);
-
- PSsetgray( NX_BLACK); // Draw the dials.
- [self drawDials];
-
-
- PStranslate( half, half);
- // Then, draw the tick marks (assume linewidth/cap set by drawDials).
- PSnewpath();
- for( i=0; i<12; i++, PSrotate( 30))
- {
- PSmoveto( TICKS, 0);
- PSlineto( half, 0);
- }
- PSstroke();
-
- [[self window] flushWindow];
- NXPing();
- return self;
- }
-
- // Here is a useful function - cut this out for your programs. This is a Window
- // delegate function which keeps the window from resizing to a non-square
- // size. It's not what I'd like, though - the resize bar still has that
- // section for resizing vertically only. When that occurs, you do not get
- // to do anything. I tried _making_ it resize, but that did not work. So,
- // this is what you get.
- - windowWillResize:sender toSize:(NXSize *)f
- {
- NXRect curFrame;
- [sender getFrame:&curFrame];
- if( curFrame.size.width==f->width || curFrame.size.height==f->height)
- {
- *f=curFrame.size;
- return self;
- }
- f->width-=curFrame.size.width;
- f->height-=curFrame.size.height;
- f->width=f->height=MAX( f->width, f->height);
- f->width+=curFrame.size.width;
- f->height+=curFrame.size.height;
- return self;
- }
-
- @end
-